package cn.kimming.rpc.remoting.codec;

import cn.kimming.rpc.common.exception.RpcException;
import cn.kimming.rpc.remoting.serialization.ISerialization;
import cn.kimming.rpc.remoting.serialization.SerializationFactory;
import cn.kimming.rpc.common.constant.SerializationWay;
import cn.kimming.rpc.common.constant.ReqFlag;
import cn.kimming.rpc.remoting.transport.RpcRequest;
import cn.kimming.rpc.remoting.transport.RpcResponse;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;

import java.util.List;

public class MyRpcProtocolClientCodec extends AbstractMyRpcProtocolCodec<RpcRequest> {

    public MyRpcProtocolClientCodec(SerializationWay serializationWay) {
        super(serializationWay);
    }


    @Override
    protected void encode(ChannelHandlerContext ctx, RpcRequest msg, ByteBuf out) throws Exception {
        // 序列化数据, 获取数据长度
        ISerialization serialization = SerializationFactory.getSerialization(serializationWay);
        byte[] dataBytes = serialization.serialize(msg);
        int dataLength = dataBytes.length;

        // 按照协议写入字节数据
        out.writeByte(ReqFlag.REQUEST.getByteVal()); // 写入请求响应标识
        out.writeByte(serializationWay.getByteVal()); // 序列化协议标识
        out.writeInt(dataLength);   // 写入数据长度
        out.writeBytes(dataBytes);  // 写入数据`
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (in.readableBytes() < HEADER_LENGTH) {
            return;
        }
        in.markReaderIndex();
        byte reqFlagByte = in.readByte();
        byte serializationByte = in.readByte();
        int dataLength = in.readInt();

        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }

        byte[] dataBytes = new byte[dataLength];
        in.readBytes(dataBytes);

        SerializationWay way = SerializationWay.getSerialization(serializationByte);
        ISerialization serialization = SerializationFactory.getSerialization(way);
        ReqFlag reqFlag = ReqFlag.getFlag(reqFlagByte);
        if (reqFlag != ReqFlag.RESPONSE) {
            throw new RpcException("无效的响应标识");
        }

        RpcResponse response = serialization.deserialize(dataBytes, RpcResponse.class);
        out.add(response);

    }
}
